/*--------------------------------------------------------------------------------------*\
**
** adv_tree_of_knowledge.cpp
**
** Heroes IV
** Copyright 2000, The 3DO Company
**
\*--------------------------------------------------------------------------------------*/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )


#include "adv_tree_of_knowledge.h"

#include "adv_object_type.h"
#include "adventure_frame.h"
#include "adventure_sounds.h"
#include "army.h"
#include "basic_dialog.h"
#include "dialog_tree_of_knowledge.h"
#include "external_string.h"
#include "music.h"
#include "object_registration.h"
#include "random.h"
#include "replace_keywords.h"
#include "simple_dialog.h"

extern t_external_string const k_text_dead_heroes_ineligible;

// Unnamed namespace
namespace
{
    t_object_registration< t_adv_tree_of_knowledge > registration( k_adv_object_tree_of_knowledge );
} // Unnamed namespace

t_adv_tree_of_knowledge::t_adv_tree_of_knowledge( std::string const& model_name )
         : t_single_use_object( model_name )
{
}

void t_adv_tree_of_knowledge::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                               t_direction direction, t_adventure_frame* frame )
{
	std::vector<t_hero*>    heroes;
	t_hero*                 hero_ptr;
	bool				    any_heroes_eligible = false;
	bool				    can_add_experience = false;
	bool				    dead_heroes = true;
	t_creature_array&       creatures = army->get_creatures();
	t_player*               player = army->get_owner();
    int i;

    /*
    ** Check for eligible heroes.
    */
	for (i = 0; i < t_creature_array::k_size; i++)
	{
		hero_ptr = creatures[i].get_hero();

        // Hero or not?        
		if (hero_ptr == 0)
			continue;

		if (hero_ptr->is_dead())
			continue;
	    dead_heroes = false;

		heroes.push_back( hero_ptr );

	    if (!(hero_ptr->can_add_experience( player )))
            continue;
	
        can_add_experience = true;
        
        // Has the hero visited?
		if (hero_ptr->has_visited( *this ))
			continue;
	    any_heroes_eligible = true;
    }

	t_sound_cache music = get_music_playing();
	stop_music();
	get_dialog_sound( k_dialog_sound_experience )->play( get_sound_volume() );

    std::string status_text;
        
    if ((heroes.size() > 0) && (can_add_experience == false))
    {
        status_text = get_text ("heroes_full");
	    ok_dialog( status_text, get_dialog_bottom( point ) );
		play_music( music );
        return;
    }
    else if (dead_heroes == true)
    {
	    status_text = get_text("heroes_dead");
        if (status_text == "")
            status_text = k_text_dead_heroes_ineligible;
		ok_dialog( status_text, get_dialog_bottom( point ) );
		play_music( music );
        return;
    }
    else if (any_heroes_eligible == false)
    {
        // There are heroes, but they've all visited..
		if (heroes.size() > 0)
        {
            status_text = get_text ("Empty");
	        ok_dialog( status_text, get_dialog_bottom( point ) );
        }
        // No heroes, show app. message...
        else
        {
            status_text = get_text ("Empty");
	        ok_dialog( status_text, get_dialog_bottom( point ) );
        }
		play_music( music );
        return;
    }

	select_heroes_dialog ( heroes, point, frame, army);
	play_music( music );
}

/*
** Show hero select dialog.
*/
void t_adv_tree_of_knowledge::select_heroes_dialog( std::vector<t_hero*> const& heroes, t_level_map_point_2d point,
										    t_window* parent, t_army* army )
{
	t_counted_ptr<t_dialog_tree_of_knowledge> dialog_ptr;
	std::string     intro_text;
    int             i;

    if (m_cost_type == k_cost_2500_gold)
    {
    	intro_text = replace_keywords( get_text("Initial"), k_cost_gold, k_gold );
    }
    else
    {
    	intro_text = replace_keywords( get_text("Initial"), k_cost_gems, k_gems );
    }
    
	dialog_ptr = new t_dialog_tree_of_knowledge( parent );
	dialog_ptr->init_dialog( heroes, get_text("name"), intro_text, get_text("help.rejected"),
                    parent, *this, army, m_cost_type);
	dialog_ptr->run_modal();

	std::vector<t_hero*>    selected_heroes;
	std::vector<int>        gained_experience;
	std::string    text;

    // Get selected heroes to upgrade.
	selected_heroes = dialog_ptr->get_selected_heroes();
    
    /*
    ** No heroes selected - this check may be unnecessary, since dialog will return
    ** if no hero selected.
    */
    if (selected_heroes.size() == 0)
        return;
    
	gained_experience = dialog_ptr->get_gained_experience();

    /*
    ** Show the text for the skill upgrade.
    */
    t_basic_dialog* result_dialog_ptr;

    result_dialog_ptr = new t_basic_dialog;
    if (m_cost_type == k_cost_2500_gold)
    {
    	text = replace_keywords( get_text("Paid"), (selected_heroes.size() * k_cost_gold), k_gold );
    }
    else
    {
    	text = replace_keywords( get_text("Paid"), (selected_heroes.size() * k_cost_gems), k_gems );
    }
    result_dialog_ptr->set_text( text );
    for (i=0; i < selected_heroes.size(); i++)
    {
		result_dialog_ptr->add_experience( gained_experience[i], selected_heroes[i] );
    }
    result_dialog_ptr->add_ok_button();
    result_dialog_ptr->open( get_dialog_bottom( point ), true, k_align_bottom );
    result_dialog_ptr->run_modal();

    // Upgrade...Give hero choice...
    for (i=0; i < selected_heroes.size(); i++)
    {
        selected_heroes[i]->check_level( *get_map(), parent, army->get_owner() );
    }
}

/*
** Pick either 2500 gold or 5 gems.
*/
void t_adv_tree_of_knowledge::initialize( t_adventure_map& map )
{

    set_cost_type ();
}

/*
** Randomly pick either 2500 gold or 5 gems.
*/
void t_adv_tree_of_knowledge::set_cost_type()
{
    m_cost_type = random(0, (k_cost_types-1));
}

int t_adv_tree_of_knowledge::get_version() const
{
	return 1;
}

bool t_adv_tree_of_knowledge::read( std::streambuf&						stream, 
									t_qualified_adv_object_type const&	type,
									int									version ) 
{
	if (version < 1)
	{
		set_cost_type();
		return true;
	}

    t_single_use_object::read( stream, type, version );
    
	m_cost_type = (int)( get<t_uint8> (stream));
	return m_visited.read( stream );
}

bool t_adv_tree_of_knowledge::write( std::streambuf& stream ) const
{
    t_single_use_object::write(stream);

	put<t_uint8>( stream, m_cost_type );
	return m_visited.write( stream );
}

void t_adv_tree_of_knowledge::visit( t_hero* hero )
{

}

